package com.color.admin.common.security.handler;

import com.alibaba.fastjson.JSONObject;
import com.color.admin.common.core.constant.Constant;
import com.color.admin.common.core.exception.BaseException;
import com.color.admin.common.core.result.ResultCode;
import com.color.admin.common.core.result.ResultData;
import com.color.admin.common.core.utils.cache.RedisUtils;
import com.color.admin.common.core.utils.web.ServletUtils;
import com.color.admin.common.core.utils.web.StringUtils;
import com.color.admin.common.core.utils.web.TokenUtils;
import com.color.admin.common.security.entity.SecurityUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author HaiQiu
 * @date 2022/2/21
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private AuthHandlerFilter authHandlerFilter;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//        System.out.println("****************\n收到请求："+request.getRequestURI()+"\n****************");
        String token = request.getHeader(TokenUtils.TOKEN_KEY);
        if (!StringUtils.isBlank(token)) {
            authHandlerFilter.authUser(token);
            String requestURI = request.getRequestURI();
            String method = request.getMethod();
            if (!authHandlerFilter.checkAuth(requestURI, method, token)) {
                sendResponse(response);
                return;
            }
            SecurityUser details = (SecurityUser) redisUtils.get(Constant.USER_SECURITY + TokenUtils.getUsernameFormToken(token));
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                    details, null, details.getAuthorities());
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        filterChain.doFilter(request, response);
    }


    /**
     * 将字符串渲染到客户端
     *
     * @param response 渲染对象
     */
    public static void sendResponse(HttpServletResponse response) {
        try {
            response.setStatus(200);
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            PrintWriter printWriter = response.getWriter();

            printWriter.write(JSONObject.toJSONString(ResultData.fail(ResultCode.NOT_AUTH.getCode(),
                    ResultCode.NOT_AUTH.getMsg())));

            printWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
